﻿using PmSoft.Core.Extensions;
using System.Collections.Concurrent;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;

namespace PmSoft.Core.Reflection;

/// <summary>
/// 快速创建类型的辅助类
/// </summary>
/// <typeparam name="T">要创建的类型</typeparam>
public static class TypeFactory<T>
{
	/// <summary>
	/// 创建类型实例的委托
	/// </summary>
	public static readonly Func<T> Instance;

	/// <summary>
	/// 根据类型创建实例的委托
	/// </summary>
	public static readonly Func<Type, T> Creator = (type) => (T)TypeFactory.CreateInstance(type);

	static TypeFactory()
	{
		Type type = typeof(T);
		if (type == typeof(string))
			Instance = () => (T)(object)string.Empty;
		else if (type.HasDefaultConstructor())
			Instance = Expression.Lambda<Func<T>>(Expression.New(type)).Compile();
		else
			Instance = () => (T)RuntimeHelpers.GetUninitializedObject(type);
	}
}

/// <summary>
/// 快速创建类型的辅助类
/// </summary>
public static class TypeFactory
{
	private static readonly ConcurrentDictionary<Type, Func<object>> _cache = new();

	/// <summary>
	/// 根据类型创建实例的委托
	/// </summary>
	public static readonly Func<Type, object> CreateInstance = (type) =>
	{
		var func = _cache.GetOrAdd(type, x =>
		{
			if (x == typeof(string))
				return () => (object)string.Empty;
			else if (x.HasDefaultConstructor())
				return Expression.Lambda<Func<object>>(Expression.New(x)).Compile();

			return () => RuntimeHelpers.GetUninitializedObject(x);
		});
		return func();
	};
}



